#include "ContextoDeEjecucionFactory.h"

using namespace servicios;


ContextoDeEjecucionFactory::ContextoDeEjecucionFactory(RequisitosDeEjecucion* otrosRequisitos)
{
	this->requisitos = otrosRequisitos;
	this->contexto = new ContextoDeEjecucion();
	this->parserYAML = new ParserYAML();
	this->informacionCarreraFactory = new InformacionCarreraFactory();
	this->informacionMateriasFactory = new InformacionMateriasFactory();
	this->restriccionesFactory = new RestriccionesFactory(this->contexto);
};

ContextoDeEjecucion* ContextoDeEjecucionFactory::Construir(ActualizadorPantallaCommand* actualizadorPantalla)
{
	this->CrearConInformacionDeCarrera(actualizadorPantalla)
		->CrearConInformacionDeMaterias(actualizadorPantalla)
		->CrearConRestriccionesDeterministicas(actualizadorPantalla)
		->CrearConRestriccionesNoDeterministicas(actualizadorPantalla);
	return this->contexto;
};

ContextoDeEjecucionFactory* ContextoDeEjecucionFactory::CrearConInformacionDeCarrera(ActualizadorPantallaCommand* actualizadorPantalla)
{
	actualizadorPantalla->Escribir(INFO_PARSEANDO_INFORMACION_CARRERA);
	InformacionCarreraYAML informacionCarreraYAML = this->parserYAML->ParsearArchivoInformacionDeCarrera(this->requisitos->GetRutaInformacionCarrera());
	this->contexto->SetInformacionCarrera(this->informacionCarreraFactory->Construir(informacionCarreraYAML));
	return this;
};

ContextoDeEjecucionFactory* ContextoDeEjecucionFactory::CrearConInformacionDeMaterias(ActualizadorPantallaCommand* actualizadorPantalla)
{
	actualizadorPantalla->Escribir(INFO_PARSEANDO_INFORMACION_MATERIAS);
	list<InformacionMateriaYAML> informacionMateriasYAML = this->parserYAML->ParsearArchivoInformacionDeMaterias(this->requisitos->GetRutaInformacionMaterias());
	list<InformacionMateria*> informacionMaterias;
	list<InformacionMateriaYAML>::iterator itInformacionMaterias;
	for(itInformacionMaterias = informacionMateriasYAML.begin(); 
		itInformacionMaterias != informacionMateriasYAML.end(); itInformacionMaterias++)
	{
		InformacionMateriaYAML informacionMateriaYAML = *itInformacionMaterias;
		informacionMaterias.push_back(this->informacionMateriasFactory->Construir(informacionMateriaYAML));
	}
	this->contexto->SetInformacionMaterias(informacionMaterias);
	return this;
};

ContextoDeEjecucionFactory* ContextoDeEjecucionFactory::CrearConRestriccionesDeterministicas(ActualizadorPantallaCommand* actualizadorPantalla)
{
	if(this->requisitos->IsTieneRestriccionesDeterministicas())
	{
		actualizadorPantalla->Escribir(INFO_PARSEANDO_RESTRICCIONES_DET);
		InformacionRestriccionesDeterministicasYAML restriccionesYAML = this->parserYAML->ParsearArchivoRestriccionesDeterministicas(this->requisitos->GetRutaRestriccionesDeterministicas()); 
		this->contexto->SetRestriccionesDeterministicas(this->restriccionesFactory->Construir(restriccionesYAML));
	} else
	{
		this->contexto->SetRestriccionesDeterministicas(this->CrearInformacionRestriccionesDeterministicasDefault());
	}
	return this;
};


ContextoDeEjecucionFactory* ContextoDeEjecucionFactory::CrearConRestriccionesNoDeterministicas(ActualizadorPantallaCommand* actualizadorPantalla)
{
	if(this->requisitos->IsTieneRestriccionesNoDeterministicas())
	{
		actualizadorPantalla->Escribir(INFO_PARSEANDO_RESTRICCIONES_NO_DET);
		InformacionRestriccionesNoDeterministicasYAML restriccionesYAML = this->parserYAML->ParsearArchivoRestriccionesNoDeterministicas(this->requisitos->GetRutaRestriccionesNoDeterministicas()); 
		this->contexto->SetRestriccionesNoDeterministicas(this->restriccionesFactory->Construir(restriccionesYAML));
	} else 
	{
		this->contexto->SetRestriccionesNoDeterministicas(this->CrearInformacionRestriccionesNoDeterministicasDefault());
	}
	return this;
};

InformacionRestriccionesDeterministicas* ContextoDeEjecucionFactory::CrearInformacionRestriccionesDeterministicasDefault()
{
	InformacionRestriccionesDeterministicas* restricciones = new InformacionRestriccionesDeterministicas();
	return restricciones;
};

InformacionRestriccionesNoDeterministicas* ContextoDeEjecucionFactory::CrearInformacionRestriccionesNoDeterministicasDefault()
{
	InformacionRestriccionesNoDeterministicas* restricciones = new InformacionRestriccionesNoDeterministicas();
	return restricciones;
};